import java.io.Serializable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * 4 双重检查（对懒汉式的升级，效率更高）
 *
 * @author agstar
 * @date 2019/7/3 10:21
 */
public class LazyDoubleCheck implements Serializable {

    private static volatile LazyDoubleCheck instance = null;

    /**
     * 构造函数私有化
     */
    private LazyDoubleCheck() {
    }

    /**
     * 提供一个全局的静态方法
     * 这样写，只把新建实例的代码放到同步锁中，
     * 为了保证线程安全再在同步锁中加一个判断，
     * 虽然看起来更繁琐，但是同步中的内容只会执行一次，
     * 执行过后，以后经过外层的if判断后，都不会在执行了，
     * 所以不会再有阻塞。程序运行的效率也会更加的高。
     */
    public static LazyDoubleCheck getInstance() {
        if (instance == null) {
            synchronized (LazyDoubleCheck.class) {
                System.out.println(Thread.currentThread().getName());
                if (instance == null) {
                    System.err.println(Thread.currentThread().getName());
                    instance = new LazyDoubleCheck();
                }
            }
        }
        return instance;
    }
    public Object readResolve(){
        return getInstance();
    }










    public static void main(String[] args) {
        int count = 20000;
        CountDownLatch latch = new CountDownLatch(count);

        for (int i = 0; i < count; i++) {
            new Thread(() -> {
                try {
                    latch.await();
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                LazyDoubleCheck lazythree = LazyDoubleCheck.getInstance();
//                System.out.println(lazythree);
            }).start();
            latch.countDown();
        }
    }



}
